import XLSX from 'xlsx'
import axios from 'axios'
import { Message } from 'element-ui'

/**
 *  columns 字段配置
 *    excelHidden : 隐藏当前列
 *    excelWidth  : 设置列宽
 **/

/**
 if (item.type === 'export') {
  this.exportSetting = {
    columns: this.columns,
    url: this.url,
    sheetName: item.sheetName || 'export-sheet',
    config: item.config || {}
  }
}
 **/
/**
 * ele-pro-table表格内数据重新请求导出excel
 * @param columns
 * @param baseQuery
 * @param requestUrl
 * @param sheetName
 * @param config
 */
export function eleTableExportExcel (columns, baseQuery, requestUrl, sheetName, config = {}) {
  return new Promise(resolve => {
    let query = JSON.parse(JSON.stringify(baseQuery))
    query.Page = 1
    query.Size = 200
    let { table, column, cols } = columnsFormat(columns)

    let res = getList(requestUrl, query).then(res => {
      table = table.concat(listFormat(res.list, column))
      if (res.count > query.ExcelLimit) {
        let pageLen = Math.ceil(res.count / query.ExcelLimit)
        let queue = []
        for (let page = 1; page < pageLen; page++) {
          query.Page = page + 1
          queue.push(getList(requestUrl, query))
        }
        Promise.all(queue).then(function (results) {
          results.forEach(listItem => {
            table = table.concat(listFormat(listItem.list, column))
          })
          exportExcelOneSheet(sheetName, table, cols, config)
        }).catch(() => {
          resolve()
        })
      } else {
        exportExcelOneSheet(sheetName, table, cols, config)
      }
    }).catch(() => {
      resolve()
    })
    Promise.all([res]).then(() => {
      resolve()
    })
  })
}

/**
 * 本地表格内数据导出为excel
 * @param columns
 * @param sheetName
 * @param data
 * @param config
 * @returns {Promise<unknown>}
 */
export function eleTableDataExportExcel (columns, sheetName, data = [], config = {}) {
  return new Promise(resolve => {
    let { table, column, cols } = columnsFormat(columns)
    table = table.concat(listFormat(data, column))
    exportExcelOneSheet(sheetName, table, cols, config)
    resolve()
  })
}

function columnsFormat (columns) {
  let table = [[]]
  let column = {
    field: [],
    formatter: {}
  }
  let cols = []
  columns.forEach(item => {
    let hide = item.excelHidden || false
    if (item.label && hide === false) {
      table[0].push(item.label + ('subTitle' in item ? "\r\n" + item.subTitle : ''))
      column['field'].push(item.prop)
      if (item.formatter) {
        column['formatter'][item.prop] = item.formatter
      }
      cols.push({
        wpx: item.excelWidth || item.width || item.minWidth || 120,
      })
    }
  })
  return { table, column, cols }
}

/**
 * 导出一个 sheet 的 excel
 * @param sheetName
 * @param table
 * @param cols
 * @param config
 */
function exportExcelOneSheet (sheetName, table = [], cols, config = {}) {

  let hpx = new Array(table.length).fill({ hpx: 20 })
  if ('style' in config) {
    config.style.forEach(line => {
      if (line.row <= hpx.length) {
        hpx[line.row] = Object.assign({}, hpx[line.row], line.style)
      }
    })
  }
  let merges = []
  if ('title' in config) {
    let index = 0
    config.title.forEach(line => {
      let result = new Array(table[0].length - 1).fill(null)
      result.unshift(line.title)
      merges.push({
        s: { c: 0, r: index },
        e: { c: result.length - 1, r: index },
      })
      index++
      table.unshift(result)
    })
  }

  let workbook = {
    SheetNames: [sheetName],
    Sheets: {
      [sheetName]: XLSX.utils.aoa_to_sheet(table)
    }
  }
  workbook.Sheets[sheetName]['!rows'] = hpx
  workbook.Sheets[sheetName]['!cols'] = cols
  if (merges.length) {
    workbook.Sheets[sheetName]['!merges'] = merges
  }
  XLSX.writeFile(workbook, sheetName + '.xlsx')
}

/**
 * 列表根据 column 格式化
 * @param list
 * @param column
 * @returns {[]}
 */
function listFormat (list, column) {
  let table = []
  list.forEach(item => {
    let data = []
    data.push(...column['field'].map(field => {
      return column['formatter'][field] ? column['formatter'][field](item, {}, item[field]) : item[field]
    }))
    table.push(data)
  })
  return table
}

/**
 * 获取分页数据
 * @param requestUrl
 * @param params
 * @returns {Promise<unknown>}
 */
function getList (requestUrl, params) {
  return new Promise((resolve, reject) => {
    axios.get(requestUrl, { params }).then(res => {
      if (res.data.code === 200) {
        if (res.data.result.count <= 0) {
          Message.error('未查询到数据！')
          reject()
          return
        }
        let list = res.data.result.list || []
        if (!(list instanceof Array) || list.length === 0) {
          Message.error('数据格式异常！')
          reject()
          return
        }
        resolve(res.data.result)
      } else {
        Message.error('数据获取失败')
      }
    }).catch(e => {
      Message.error('导出失败：' + e.message)
      reject(e)
    })
  })
}
